Avoid overflow when converting coordinates to Pango units. (#332266, Jody
authorBehdad Esfahbod <behdad@gnome.org>
Fri, 5 Jan 2007 06:16:32 +0000 (06:16 +0000)
committerBehdad Esfahbod <behdad@src.gnome.org>
Fri, 5 Jan 2007 06:16:32 +0000 (06:16 +0000)
2007-01-05  Behdad Esfahbod  <behdad@gnome.org>

        * gdk/gdkprivate.h:
        * gdk/gdkpango.c (gdk_draw_layout_line_with_colors),
        (gdk_draw_layout_with_colors):
        * gdk/gdkwindow.c (gdk_window_draw_glyphs_transformed):
        Avoid overflow when converting coordinates to Pango units. (#332266,
        Jody Goldberg)

svn path=/trunk/; revision=17075

ChangeLog
gdk/gdkpango.c
gdk/gdkprivate.h
gdk/gdkwindow.c

index 2c6b9a4df65ae2237cfcf38ddcc72d177bec2f05..7c4c217f602d67d86058dfd80767e2c37b425dac 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-01-05  Behdad Esfahbod  <behdad@gnome.org>
+
+       * gdk/gdkprivate.h:
+       * gdk/gdkpango.c (gdk_draw_layout_line_with_colors),
+       (gdk_draw_layout_with_colors):
+       * gdk/gdkwindow.c (gdk_window_draw_glyphs_transformed):
+       Avoid overflow when converting coordinates to Pango units. (#332266,
+       Jody Goldberg)
+
 2007-01-04  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkcombobox.c (gtk_combo_box_popup): move set_cursor
index d04aa9963e48c32368b432ae39a96f61a0846f22..54c0c961c837009259ea8c041d8e259e7a19b687 100644 (file)
@@ -844,8 +844,22 @@ gdk_draw_layout_line_with_colors (GdkDrawable      *drawable,
       PangoMatrix tmp_matrix;
       
       tmp_matrix = *matrix;
-      tmp_matrix.x0 = x;
-      tmp_matrix.y0 = y;
+      tmp_matrix.x0 += x;
+      tmp_matrix.y0 += y;
+      pango_renderer_set_matrix (renderer, &tmp_matrix);
+
+      x = 0;
+      y = 0;
+    }
+  /* Fall back to introduce a matrix if the coords would scale out of range.
+   * The x and y here will be added to in-layout coordinates.  So we cannot
+   * support the entire range here safely.  So, we just accept the middle half
+   * and use fallback for the rest. */
+  else if (GDK_PANGO_UNITS_OVERFLOWS (x, y))
+    {
+      PangoMatrix tmp_matrix = PANGO_MATRIX_INIT;
+      tmp_matrix.x0 += x;
+      tmp_matrix.y0 += y;
       pango_renderer_set_matrix (renderer, &tmp_matrix);
 
       x = 0;
@@ -965,6 +979,16 @@ gdk_draw_layout_with_colors (GdkDrawable     *drawable,
       tmp_matrix.y0 += y - rect.y;
       pango_renderer_set_matrix (renderer, &tmp_matrix);
       
+      x = 0;
+      y = 0;
+    }
+  else if (GDK_PANGO_UNITS_OVERFLOWS (x, y))
+    {
+      PangoMatrix tmp_matrix = PANGO_MATRIX_INIT;
+      tmp_matrix.x0 = x;
+      tmp_matrix.y0 = y;
+      pango_renderer_set_matrix (renderer, &tmp_matrix);
+
       x = 0;
       y = 0;
     }
index 4dcbfe6d60f8b1bf806c5279c195decc10e28a0e..95af2e151f9f11e83fe4090ac6e0bed5332fd40a 100644 (file)
@@ -50,6 +50,16 @@ void gdk_synthesize_window_state (GdkWindow     *window,
                                   GdkWindowState unset_flags,
                                   GdkWindowState set_flags);
 
+/* Tests whether a pair of x,y may cause overflows when converted to Pango
+ * units (multiplied by PANGO_SCALE).  We don't allow the entire range, leave
+ * some space for additions afterwards, to be safe...
+ */
+#define GDK_PANGO_UNITS_OVERFLOWS(x,y) (G_UNLIKELY ( \
+       (y) >= PANGO_PIXELS (G_MAXINT-PANGO_SCALE)/2 || \
+       (x) >= PANGO_PIXELS (G_MAXINT-PANGO_SCALE)/2 || \
+       (y) <=-PANGO_PIXELS (G_MAXINT-PANGO_SCALE)/2 || \
+       (x) <=-PANGO_PIXELS (G_MAXINT-PANGO_SCALE)/2))
+
 G_END_DECLS
 
 #endif /* __GDK_PRIVATE_H__ */
index 66428f5478ca26383bbeeb4e7d9cac43d1430aba..3739b8ea98377a318cd24d26c7d04b855eb5e29d 100644 (file)
@@ -1737,6 +1737,15 @@ gdk_window_draw_glyphs_transformed (GdkDrawable      *drawable,
          tmp_matrix.y0 -= y_offset;
          matrix = &tmp_matrix;
        }
+      else if (GDK_PANGO_UNITS_OVERFLOWS (x_offset, y_offset))
+       {
+         PangoMatrix identity = PANGO_MATRIX_INIT;
+         
+         tmp_matrix = identity;
+         tmp_matrix.x0 -= x_offset;
+         tmp_matrix.y0 -= y_offset;
+         matrix = &tmp_matrix;
+       }
       else
        {
          x -= x_offset * PANGO_SCALE;